﻿using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;

namespace library
{
    public class ValueHits<T> : List<ValueHitsItem<T>>
    {
        public void Add(T value)
        {
            this.Add(value, 1);
        }

        public void Add(T value, int initial_hits)
        {
            ValueHitsItem<T> actual = this.FirstOrDefault(x => x.HitValue.Equals(value));

            if (actual == null)
            {
                lock(this)
                    Add(new ValueHitsItem<T>(value, initial_hits));
            }
            else
            {
                actual.Hits += initial_hits;
            }
        }

        public void AddRange(IEnumerable<T> values)
        {
            foreach (var item in values)
                Add(item);
        }

        public void AddRange(ValueHits<T> values)
        {
            foreach (var item in values)
                Add(item.HitValue, item.Hits);
        }


        public ValueHits()
        { }

        ValueHits(IEnumerable<ValueHitsItem<T>> items)
            : base(items)
        { }

        public ValueHits<T> Tops()
        {
            var avg = (double)this.Sum(x => x.Hits) / this.Count();

            if (avg == 0)
                avg = 1;

            return new ValueHits<T>(this.Where(x => x.Hits >= avg).Take(5));
        }

        //public byte[] ToBytes()
        //{
        //    var result = new List<byte>();

        //    foreach (var item in this)
        //        result.AddRange(item.ToBytes());

        //    return result.ToArray();                 
        //}
    }

    public class ValueHitsItem<T>
    {
        [JsonProperty("V")]
        public T HitValue;

        [JsonProperty("H")]
        public int Hits;

        public ValueHitsItem(T value, int initial_hits = 1)
        {
            HitValue = value;

            Hits = initial_hits;
        }

        //public byte[] ToBytes()
        //{
        //    return BitConverter.GetBytes(Hits).
        //        Concat(Value.ToBytes()).ToArray();
        //}
    }

    //public interface ISerializable
    //{
    //    byte[] ToBytes();
    //}
}
